import re
import urllib
import logging


from lyricemo.final_pattern import emodict
from LyricStructure.pylyric.Lyric import Lyric

###
# get the emo dictionary
###
def get_pattern_list(k):
    from lyricsplit.models import LyricLrc
    from lyricemo.models import EmoWord,EmoPattern
    desp_list = []
    lrc = LyricLrc.get(k)
    for ep in EmoPattern.all().filter("lrc =",lrc):
        desp_list.append( 
                {
                    'desp':ep.desp,
                    'add_dt':str(ep.add_dt),
                    'anno_ip':ep.anno_ip
                    }
                )
    return desp_list


###
# emo word part
###
def get_emodict():
    try:
        from google.appengine.api import memcache
        from lyricemo.models import EmoWord,EmoPattern
    except:
        return emodict
    emo_dict = memcache.get('emo_dict')
    if emo_dict is None:
        emo_dict = emodict
        for ew in EmoWord.all():
            if ew.v == 0:
                if emo_dict.has_key(ew.w):
                    del emo_dict[ew.w]
            else:
                emo_dict[ew.w] = ew.v
        memcache.set('emo_dict',emo_dict,3600*12)
    return emo_dict

def get_c2wlist():
    try:
        from google.appengine.api import memcache
    except:
        emo_dict = get_emodict()
        c2wlist = {}
        for w in emo_dict.keys():
            if not c2wlist.has_key(w[0]):
                c2wlist[w[0]] = []
            c2wlist[w[0]].append( w )
        return c2wlist
    c2wlist = memcache.get('c2wlist')
    if c2wlist is None:
        emo_dict = get_emodict()
        c2wlist = {}
        for w in emo_dict.keys():
            if not c2wlist.has_key(w[0]):
                c2wlist[w[0]] = []
            c2wlist[w[0]].append( w )
        memcache.set('c2wlist',c2wlist,3600*12)
    return c2wlist

def force_update_emodict():
    from google.appengine.api import memcache
    from lyricemo.models import EmoWord,EmoPattern
    if 1:
        emo_dict = emodict
        for ew in EmoWord.all():
            if ew.v == 0:
                if emo_dict.has_key(ew.w):
                    del emo_dict[ew.w]
            else:
                emo_dict[ew.w] = ew.v
        memcache.set('emo_dict',emo_dict,3600)

        c2wlist = {}
        for w in emo_dict.keys():
            if not c2wlist.has_key(w[0]):
                c2wlist[w[0]] = []
            c2wlist[w[0]].append( w )
        memcache.set('c2wlist',c2wlist,3600)


def split_by_emoword(line,emo_dict=None,c2wlist=None):
    # TODO ,rewrite the algorithm
    # TODO , move to commontool utils

    if emo_dict is None and c2wlist is None:
        #logging.error('this init from cache cost many time')
        emo_dict = get_emodict()
        c2wlist = get_c2wlist()
    winfo_list = []

    # get all word
    w_list = []
    tmp_w_dic = {}
    for c in line:
        if c2wlist.has_key(c):
            for w in c2wlist[c]:
                tmp_w_dic[w] = 1

    #logging.error('org len:%d'%len(emo_dict.keys()))
    #logging.error('now len:%d'%len(tmp_w_dic.keys()))
    #for w in emo_dict.keys():
    for w in tmp_w_dic.keys():
        if line.count(w) != 0:
            w_list.append(w)

    # get the position info for the word list
    # merge the word
    for w in w_list:
        for m in re.finditer(w,line):
            winfo_list.append( (w,m.start(),m.end()) )
            #logging.debug(w)
    
    winfo_list.sort(lambda x,y:cmp(x[1],y[1]))
    
    # return the split line
    #logging.debug('begin of while')
    while 1:
        found = False
        for i,w_item in enumerate(winfo_list):
            #for j in reversed(range(i+1,len(winfo_list))):
            for j in reversed(range(len(winfo_list))):
                if i == j:
                    continue
                if  winfo_list[i][1] <= winfo_list[j][1] and\
                        winfo_list[i][2] >= winfo_list[j][2]:
                    # remove the j
                    del winfo_list[j]
                    found = True
                    if found:
                        break
            if found:
                break
        if not found:
            break
    #logging.debug('end of while')

    for i in reversed(range(1,len(winfo_list))):
        if winfo_list[i][1] < winfo_list[i-1][2]:
            del winfo_list[i]

    r_list = []
    if len(winfo_list) == 0:
        r_list.append({'w':line})
    
    for i,w_item in enumerate(winfo_list):
        # beginning of a sentence
        if i == 0 and w_item[1] != 0:
            tmpdic = {}
            tmpdic['w'] = line[:w_item[1]]
            r_list.append(tmpdic)

        # words between emoword
        if i != 0:
            if winfo_list[i-1][2] != winfo_list[i][1]:
                tmpdic = {}
                tmpdic['w'] = line[winfo_list[i-1][2]:winfo_list[i][1]]
                r_list.append(tmpdic)

        # emoword
        tmpdic = {}
        tmpdic['w'] = w_item[0]
        tmpdic['emo'] = emo_dict[w_item[0]]
        tmpdic['start'] = w_item[1]
        tmpdic['end'] = w_item[2]
        r_list.append(tmpdic)
        
        # the end of the sentence
        if i == len(winfo_list) - 1 and w_item[2] < len(line):
            tmpdic = {}
            tmpdic['w'] = line[w_item[2]:]
            r_list.append(tmpdic)

    return r_list

def get_split_list(lrcstr):
    """
    get split_list from lrcstr
    """
    emo_dict = get_emodict()
    c2wlist = get_c2wlist()
    l = Lyric()
    l.loadstr(lrcstr)
    line_list = l.getlinelist()
    split_list = []
    for line_item in line_list:
        split_line = split_by_emoword( line_item['content'] ,emo_dict,c2wlist)
        split_list.append(split_line)
    return split_list
